<?php

namespace tmcore\services\addons;

use think\Exception;
use think\facade\Db;
use tmcore\services\CacheService;
use think\helper\Str;

/**
 * 插件工具类
 */
class UtilService
{

    /**
     * 获取addons路径
     * @return string
     */
    public static function getAddonsPath(): string
    {
        // 插件目录
        $addons_path = app()->getRootPath() . 'addons' . DIRECTORY_SEPARATOR;
        // 如果插件目录不存在则创建
        if (!is_dir($addons_path)) {
            @mkdir($addons_path, 0755, true);
        }

        return $addons_path;
    }

    /**
     * 获取已安装插件标识列表
     * @return array
     */
    public static function getInstallAddons(): array
    {
        $addons = CacheService::get("addon_install_keys");
        $table = 'addons';
        $prefix = env('database.prefix', 'tm_');
        if (empty($addons) && Db::query("SHOW TABLES LIKE '{$prefix}{$table}'")) {
            $addons = Db::name($table)->column('identify');
            if (empty($addons)) {
                CacheService::set("addon_install_keys", []);
            } else {
                CacheService::set("addon_install_keys", $addons);
            }
        }
        return $addons?:[];
    }

    /**
     * 刷新已安装插件标识列表
     * @return array
     */
    public static function refreshInstallAddons(): array
    {
        $addons = Db::name('addons')->column('identify');
        if (empty($addons)) {
            CacheService::set("addon_install_keys", []);
        } else {
            CacheService::set("addon_install_keys", $addons);
        }
        return $addons?:[];
    }


    /**
     * 获取插件目录下的文件
     * @param $path
     * @return array
     */
    public static function getAddonsDirFiles($path): array
    {
        $addon_path = self::getAddonsPath();
        $results = scandir($addon_path . $path);
        $files = [];
        foreach ($results as $name) {
            if (in_array($name, ['.', '..'])) {
                continue;
            }

            $dir = $addon_path . $path . $name . DIRECTORY_SEPARATOR;
            if (is_dir($dir)) {
                $res = self::getAddonsDirFiles($path . $name . DIRECTORY_SEPARATOR);
                if($res) $files = array_merge($files, $res);
                continue;
            }

            if (is_file($addon_path . $path . $name)) {
                $files[] = $path . $name;
            }
        }

        return $files;
    }

    /**
     * 获取插件类的类名
     * @param string $name 插件名
     * @param string $type 命名空间类型
     * @param string $class 当前类名
     * @return string
     */
    public static function getAddonsClass($name, $type = 'controller', $class = null) : string
    {
        $name = trim($name);
        // 处理多级控制器情况
        if (!is_null($class) && strpos($class, '.')) {
            $class = explode('.', $class);
            $class[count($class) - 1] = Str::studly(end($class));
            $class = implode('\\', $class);

        } else {
            $class = Str::studly(is_null($class) ? $name : $class);
        }

        switch ($type) {
            case 'controller':
                $namespace = '\\addons\\' . $name . '\\controller\\' . $class;
                break;
            case 'event':
                $namespace = '\\addons\\' . $name . '\\listener\\' . $class;
                break;
            default:
                $namespace = '';
        }

        return ($namespace && class_exists($namespace)) ? $namespace : '';
    }

    /**
     * 获取插件配置信息
     * @param $name
     * @return array
     */
    public static function getAddonsConfig($name): array
    {
        $key = "addon_{$name}_config";
        $info = CacheService::get($key, []);
        if ($info) return $info;

        $infoFile = self::getAddonsPath() . $name . DIRECTORY_SEPARATOR . 'info.php';
        if (is_file($infoFile)) {
            $tempArr = (array) include $infoFile;
            foreach ($tempArr as $key => $value) {
                $info[$key] = $value;
            }
            unset($tempArr);
            CacheService::set($key, $info);
        }

        return $info;
    }

    /**
     * 获取json文件内容
     * @param string $json_path
     * @return array|mixed
     */
    public static function getJsonFileContent(string $json_path)
    {
        if (file_exists($json_path)) {
            $content_json = @file_get_contents($json_path);
            return json_decode($content_json, true);
        } else
            return [];
    }

    /**
     * json文件写入
     * @param array $content
     * @param string $file_path
     * @return true
     * @throws Exception
     */
    public static function writeJsonFile(array $content, string $file_path)
    {
        $content_json = json_encode($content, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        $content_json = preg_replace('/\[\]/', '{}', $content_json);
        $result = @file_put_contents($file_path, $content_json);
        if (!$result) {
            throw new Exception($file_path . '文件不存在或者权限不足');
        }
        return true;
    }


    /**
     * 获取打包目录
     * @param $commandParams
     * @return array|false
     */
    public static function getBuildDirs($commandParams = '')
    {
        if(empty($commandParams)) return false;

        if (stripos($commandParams, '.')) {
            $commandArr = explode('.', $commandParams);
        } else {
            $commandArr = [$commandParams];
        }

        $root_path = app()->getRootPath();
        $sys_path = dirname($root_path) . DIRECTORY_SEPARATOR;

        // 检验包含打包流程
        if(in_array('build', $commandArr)) {
            if($commandArr[0] == 'admin') {
                $dist_file_arr = [
                    $sys_path. 'admin/dist/index.html',
                    $sys_path. 'admin/dist/assets',
                    $sys_path. 'admin/dist/favicon.ico',
                ];
                $to_file_arr = [
                    $root_path. 'public/admin/index.html',
                    $root_path. 'public/admin/assets',
                    $root_path. 'public/admin/favicon.ico',
                ];
            } elseif($commandArr[0] == 'uniapp') {
                $dist_file_arr = [
                    $sys_path. 'uniapp/dist/build/h5/index.html',
                    $sys_path. 'uniapp/dist/build/h5/assets',
                    $sys_path. 'uniapp/dist/build/h5/static',
                ];
                $to_file_arr = [
                    $root_path. 'public/app/index.html',
                    $root_path. 'public/app/assets',
                    $root_path. 'public/app/static',
                ];
            } elseif($commandArr[0] == 'pc') {
                $dist_file_arr = [
                    $sys_path. 'pc/dist/_nuxt',
                    $sys_path. 'pc/dist/200.html',
                    $sys_path. 'pc/dist/404.html',
                    $sys_path. 'pc/dist/favicon.ico',
                    $sys_path. 'pc/dist/index.html',
                ];
                $to_file_arr = [
                    $root_path. 'public/pc/_nuxt',
                    $root_path. 'public/pc/200.html',
                    $root_path. 'public/pc/404.html',
                    $root_path. 'public/pc/favicon.ico',
                    $root_path. 'public/pc/index.html',
                ];
            } else {
                return false;
            }

            return [
                'dist_file_arr' => $dist_file_arr,
                'to_file_arr' => $to_file_arr,
                'command_arr' => $commandArr,
            ];
        }

        return false;
    }

    /**
     * 获取执行命令
     * @param string $identify 插件标识
     * @return array
     */
    public static function getExecCommands($identify)
    {
        if(!$identify) return [];

        $savePath = com_get_path('data') . 'addons/' . $identify;
        $sysPath = dirname(app()->getRootPath());

        $execute_commands = [];

        // 服务端
        if(is_dir($savePath . '/server') && file_exists($savePath . '/package/composer.json')) {
            $execute_commands[] = 'server.install';
        }

        // 管理端
        if(is_dir($savePath . '/admin')) {
            if(file_exists($savePath . '/package/admin_package.json') || (!is_dir($sysPath . '/admin/node_modules'))) $execute_commands[] = 'admin.install';
            $execute_commands[] = 'admin.build';
        }

        // 手机端
        if(is_dir($savePath . '/uniapp')) {
            if(file_exists($savePath . '/package/uniapp_package.json') || (!is_dir($sysPath . '/uniapp/node_modules'))) $execute_commands[] = 'uniapp.install';
            $execute_commands[] = 'uniapp.build';
        }

        // 电脑端
        if(is_dir($savePath . '/pc')) {
            if(file_exists($savePath . '/package/pc_package.json') || (!is_dir($sysPath . '/pc/node_modules'))) $execute_commands[] = 'pc.install';
            $execute_commands[] = 'pc.build';
        }

        return $execute_commands;
    }
}